package com.spzx.cart.service.impl;

import com.spzx.cart.domain.CartInfo;
import com.spzx.cart.service.CartService;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.domain.ProductSku;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.BoundGeoOperations;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class CartServiceImpl implements CartService {
    @Resource
    RedisTemplate redisTemplate;

    @Resource
    RemoteProductService remoteProductService;
    //加购业务方法
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取当前用户的购物车：  购物车数据存在redis中 使用用户的id拼接唯一的key存储
        Long userId = SecurityUtils.getUserId(); //购物车的路径没有设置到网关的白名单中，可以被网关的AuthFilter鉴权，必须登录后才可以访问
        BoundHashOperations<String, String, CartInfo> cart = getCart();
        //1、如果当前用户的购物车中存在 skuId的购物项，更新数量+skuNum
        CartInfo cartInfo = cart.get(skuId.toString());
        if(cartInfo!=null){
            //更新数量
            cartInfo.setSkuNum(cartInfo.getSkuNum()+skuNum);
            cartInfo.setUpdateTime(new Date());
            //将数据同步到redis中
            //            cart.put(skuId.toString(),cartInfo);
        }
        //2、如果不存在 新建购物项(CartInfo)存到当前用户的购物车中
        else{
            cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setIsChecked(1);//默认选中
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());

            //购物项需要的数据 前端只传了skuId，sku的其它数据需要访问product服务查询!
            R<ProductSku> productSkuR = remoteProductService.getSkuById(skuId);
            if(productSkuR.getCode()!=200){
                throw new ServiceException(productSkuR.getMsg());
            }
            ProductSku productSku = productSkuR.getData();
            //加购价格
            cartInfo.setCartPrice(productSku.getSalePrice());
            //实时价格
            cartInfo.setSkuPrice(productSku.getSalePrice());

            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
        }
        //新增或更新购物车中的购物项
        cart.put(skuId.toString(),cartInfo);

    }

    @Override
    public List<CartInfo> cartList() {
        //获取购物车 所有的购物项
        return getCart().values();
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        BoundHashOperations<String, String, CartInfo> cart = getCart();
        //查找购物项
        CartInfo cartInfo = cart.get(skuId.toString());
        if(cartInfo==null){
            throw new ServiceException("购物项不存在");
        }

        cartInfo.setIsChecked(isChecked);
        cartInfo.setUpdateTime(new Date());

        //设置到redis中
        cart.put(skuId.toString() , cartInfo);
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        BoundHashOperations<String, String, CartInfo> cart = getCart();
        //遍历所有的购物项修改他们的选中状态
        cart.entries().forEach((k,cartInfo)->{
            cartInfo.setIsChecked(isChecked);
            cartInfo.setUpdateTime(new Date());
            //更新数据
            cart.put(k , cartInfo);
        });

    }

    //泛型1： redis键的类型， 参数2：hash结构key的类型 参数3：hash值的类型
    private BoundHashOperations<String,String , CartInfo> getCart() {
        Long userId = SecurityUtils.getUserId();
        String cartKey = "spzx:cart:"+ userId;
        //双层map： 第一层： userId -> Hash   第二层： skuId-> cartInfo对象
        BoundHashOperations<String,String , CartInfo> cart = redisTemplate.boundHashOps(cartKey);
        return cart;
    }
    //删除指定购物项
    @Override
    public void deleteCart(Long skuId) {
        getCart().delete(skuId.toString());
    }
    //清空购物车
    @Override
    public void clearCart() {
        //删除整个hash结构
        redisTemplate.delete("spzx:cart:"+SecurityUtils.getUserId());
    }

    @Override
    public List<CartInfo> cartListByUserId(Long userId) {
        String cartKey = "spzx:cart:"+ userId;
        //双层map： 第一层： userId -> Hash   第二层： skuId-> cartInfo对象
        BoundHashOperations<String,String , CartInfo> cart = redisTemplate.boundHashOps(cartKey);
        //获取购物车中所有的购物项，然后过滤选中状态为1的 返回
        return cart.values().stream()
                .filter(cartInfo -> cartInfo.getIsChecked().intValue()==1)
                .collect(Collectors.toList());
    }

    @Override
    public boolean deleteCheckedCartInfo(Long userId) {
        String cartKey = "spzx:cart:"+ userId;
        //双层map： 第一层： userId -> Hash   第二层： skuId-> cartInfo对象
        BoundHashOperations<String,String , CartInfo> cart = redisTemplate.boundHashOps(cartKey);

        cart.values() //获取购物车中所有的购物项
                .stream()
                .filter(cartInfo -> cartInfo.getIsChecked().intValue()==1) //挑选选中的购物项
                .forEach(cartInfo -> {//遍历选中的购物项
                    cart.delete(cartInfo.getSkuId().toString()); //删除遍历的购物项
                });

        return true;
    }
}